

package com.kimo.shop.admin.controller;

import java.util.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kimo.shop.bean.enums.DeliveryType;
import com.kimo.shop.bean.model.OrderRefund;
import com.kimo.shop.bean.param.OrderParam;
import com.kimo.shop.bean.vo.UnDeliveryOrderExcelVO;
import com.kimo.shop.common.annotation.SysLog;
import com.kimo.shop.common.exception.KimoShopBindException;
import com.kimo.shop.common.i18n.I18nMessage;
import com.kimo.shop.common.i18n.LanguageEnum;
import com.kimo.shop.delivery.comment.param.DeliveryOrderItemParam;
import com.kimo.shop.delivery.comment.service.DeliveryOrderService;
import com.kimo.shop.security.admin.util.SecurityUtils;
import com.kimo.shop.service.*;

import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


import com.kimo.shop.common.util.PageParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.kimo.shop.bean.enums.OrderStatus;
import com.kimo.shop.bean.model.Order;
import com.kimo.shop.bean.model.OrderItem;
import com.kimo.shop.bean.model.UserAddrOrder;
import com.kimo.shop.bean.param.DeliveryOrderParam;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author kimo-taozhouchuan on 2018/09/15.
 */
@Controller
@RequestMapping("/order/order")
@RequiredArgsConstructor
public class OrderController {

    @Value("${kimo.expose.permission:}")
    private Boolean permission;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private UserAddrOrderService userAddrOrderService;

    @Autowired
    private ProductService productService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private OrderRefundService orderRefundService;

    @Autowired
    private OrderExcelService orderExcelService;

    @Autowired
    private DeliveryOrderService deliveryOrderService;

    /**
     * 分页获取
     */
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('order:order:page')")
    public ResponseEntity<IPage<Order>> page(OrderParam orderParam,PageParam<Order> page) {
        Long shopId = SecurityUtils.getSysUser().getShopId();
        orderParam.setShopId(shopId);
        orderParam.setLang(I18nMessage.getDbLang());
        IPage<Order> orderPage = orderService.pageOrdersDetialByOrderParam(page, orderParam);
        if (BooleanUtil.isFalse(permission)){
            for (Order record : orderPage.getRecords()) {
                if (Objects.nonNull(record.getReceiverMobile())) {
                    record.setReceiverMobile(PhoneUtil.hideBetween(record.getReceiverMobile()).toString());
                }
                UserAddrOrder userAddrOrder = record.getUserAddrOrder();
                if (Objects.nonNull(userAddrOrder.getMobile())) {
                    userAddrOrder.setMobile(PhoneUtil.hideBetween(userAddrOrder.getMobile()).toString());
                }
            }
        }
        return ResponseEntity.ok(orderPage);
    }

    /**
     * 获取信息
     */
    @GetMapping("/orderInfo/{orderNumber}")
    @PreAuthorize("@pms.hasPermission('order:order:info')")
    public ResponseEntity<Order> info(@PathVariable("orderNumber") String orderNumber) {
        Long shopId = SecurityUtils.getSysUser().getShopId();
        Order order = orderService.getOrderByOrderNumberAndShopId(orderNumber,shopId,true);
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber, I18nMessage.getDbLang());
        order.setOrderItems(orderItems);
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());
        order.setUserAddrOrder(userAddrOrder);
        return ResponseEntity.ok(order);
    }

    /**
     * 发货
     */
    @PutMapping("/delivery")
    @PreAuthorize("@pms.hasPermission('order:order:delivery')")
    public ResponseEntity<Void> delivery(@RequestBody DeliveryOrderParam deliveryOrderParam) {
        Long shopId = SecurityUtils.getSysUser().getShopId();
        Order order = orderService.getOrderByOrderNumberAndShopId(deliveryOrderParam.getOrderNumber(),shopId,true);

        if (!Objects.equals(order.getStatus(), OrderStatus.PADYED.value())){
            // 订单不处于待发货状态，无法进行发货
            throw new KimoShopBindException("kimo.order.delivery.no.right");
        }
        List<OrderRefund> orderRefunds = orderRefundService.getProcessingOrderRefundByOrderId(order.getOrderId());

        if (CollectionUtil.isNotEmpty(orderRefunds)) {
            // 该订单有退款信息正在处理当中，请处理完毕之后再进行发货的操作
            throw new KimoShopBindException("kimo.order.delivery.refund.error");
        }
        Order orderParam = new Order();
        orderParam.setOrderId(order.getOrderId());
        orderParam.setDvyId(deliveryOrderParam.getDvyId());
        orderParam.setDvyFlowId(deliveryOrderParam.getDvyFlowId());
        orderParam.setDvyTime(new Date());
        orderParam.setUpdateTime(new Date());
        orderParam.setStatus(OrderStatus.CONSIGNMENT.value());
        orderParam.setUserId(order.getUserId());

        orderService.delivery(orderParam);

        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(deliveryOrderParam.getOrderNumber(), I18nMessage.getDbLang());
        for (OrderItem orderItem : orderItems) {
            productService.removeProdCacheByProdId(orderItem.getProdId(), LanguageEnum.LANGUAGE_EN.getLang());
            productService.removeProdCacheByProdId(orderItem.getProdId(),LanguageEnum.LANGUAGE_ZH_CN.getLang());
            skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId(), LanguageEnum.LANGUAGE_ZH_CN.getLang());
            skuService.removeSkuCacheBySkuId(orderItem.getSkuId(),orderItem.getProdId(), LanguageEnum.LANGUAGE_EN.getLang());
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 修改订单金额
     */
    @PutMapping("/changeAmount")
    public ResponseEntity<Void> changeAmount(@RequestBody Order order) {
        if(order.getFreightAmount()<0){
            // 运费不能小于零
            throw new KimoShopBindException("kimo.product.dvy.fee");
        }
        if(Objects.isNull(order.getFreightAmount())){
            order.setFreightAmount(0.00);
        }
        orderService.changeAmount(order);
        return ResponseEntity.ok().build();
    }

    /**
     * 修改用户订单地址
     *
     * @param order
     * @return 是否修改成功
     */
    @SysLog("修改用户订单地址")
    @PutMapping("/changeUserAddr")
    public ResponseEntity<String> changeUserAddr(@RequestBody @Valid Order order) {
        Order orderDb = orderService.getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderId, order.getOrderId())
                .eq(Order::getOrderNumber,order.getOrderNumber())
        );
        if (orderDb.getStatus() <= OrderStatus.PADYED.value() || Objects.equals(orderDb.getStatus(),OrderStatus.WAIT_GROUP.value())){
            UserAddrOrder userAddrOrder = order.getUserAddrOrder();
            userAddrOrderService.updateById(userAddrOrder);
        }else {
            // 订单状态异常，无法更改订单地址
            throw new KimoShopBindException("kimo.order.unrecognized.prod");
        }
        // 修改成功
        return ResponseEntity.ok().body(I18nMessage.getMessage("kimo.activity.update.success"));
    }

    /**
     * 修改订单备注
     *
     * @param order
     * @return 是否修改成功
     */
    @SysLog("修改订单备注")
    @PutMapping("/changeOrderRamark")
    public ResponseEntity<String> changeOrderRamark(@RequestBody @Valid Order order) {
        Order orderDb = orderService.getOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderId, order.getOrderId())
                .eq(Order::getOrderNumber,order.getOrderNumber())
        );
        orderDb.setShopRemarks(order.getShopRemarks());
        orderService.updateById(orderDb);
        // 修改成功
        return ResponseEntity.ok().body(I18nMessage.getMessage("kimo.activity.update.success"));
    }

    @GetMapping("/getOrderByUserId")
    public ResponseEntity<IPage<Order>> getOrderByUserId(PageParam<Order> page, String userId){
        IPage<Order> pages = orderService.pageByUserId(page,userId);
        return ResponseEntity.ok(pages);
    }

    /**
     * 已销售订单
     *
     * @param orderParam
     */
    @GetMapping("/soldExcel")
    @PreAuthorize("@pms.hasPermission('order:order:soldExcel')")
    public void soldExcel(OrderParam orderParam, HttpServletResponse response) {
        orderExcelService.soldExcel(orderParam,response);
    }
    @GetMapping("/unDeliveryOrderExcel")
    @ApiOperation(value = "导出待发货订单")
    @PreAuthorize("@pms.hasPermission('order:order:exportunorder')")
    public void unDeliveryOrderExcel(OrderParam orderParam, HttpServletResponse response) {
        Long shopId = SecurityUtils.getSysUser().getShopId();
        orderParam.setShopId(shopId);
        orderExcelService.unDeliveryOrderExcel(orderParam, response);
    }

    @ApiOperation(value = "导入待发货文件")
    @PostMapping("/exportOrderExcel")
    @ResponseBody
    @PreAuthorize("@pms.hasPermission('order:order:exportunorder')")
    public ResponseEntity<String> exportOrderExcel(@RequestParam("orderExcelFile") MultipartFile orderExcelFile) throws Exception {
        if (Objects.isNull(orderExcelFile)) {
            throw new KimoShopBindException("kimo.network.busy");
        }
        Long shopId = SecurityUtils.getSysUser().getShopId();
        List<UnDeliveryOrderExcelVO> orderList = new ArrayList<>();
        String errorMsg = orderExcelService.exportOrderExcel(orderExcelFile, shopId, orderList);
        if (Objects.nonNull(errorMsg)) {
            return ResponseEntity.ok(errorMsg);
        }
        //无错误再发货
        for (UnDeliveryOrderExcelVO orderExcelVO : orderList) {
            DeliveryOrderItemParam deliveryOrderParam = new DeliveryOrderItemParam();
            deliveryOrderParam.setOrderNumber(orderExcelVO.getOrderNumber());
            deliveryOrderParam.setDeliveryType(orderExcelVO.getDvyType());
            if (Objects.equals(orderExcelVO.getDvyType(), DeliveryType.EXPRESS.getValue())) {
                deliveryOrderParam.setDvyFlowId(orderExcelVO.getDvyFlowId());
                deliveryOrderParam.setDvyId(orderExcelVO.getDvyId());
            }
            List<OrderItem> selectOrderItems = new ArrayList<>();
            for (OrderItem orderItem : orderExcelVO.getOrderItemList()) {
                OrderItem deliveryItem = new OrderItem();
                deliveryItem.setOrderItemId(orderItem.getOrderItemId());
                deliveryItem.setChangeNum(orderItem.getStatus() == -1 ? orderItem.getChangeNum() : orderItem.getStatus());
                deliveryItem.setStatus(orderItem.getStatus());
                deliveryItem.setProdCount(orderItem.getChangeNum());
                selectOrderItems.add(deliveryItem);
            }
            deliveryOrderParam.setSelectOrderItems(selectOrderItems);
            deliveryOrderService.saveDeliveriesInfo(deliveryOrderParam);
        }
        return ResponseEntity.ok("导入成功！");
    }
}
